OCaml
- Descendente do ML (através do Caml)
- "Híbrida" ("O" = Objective)
- Avaliação estrita
- Impura, porém incentiva programação pura
- Compilador e runtime com bom desempenho
- Módulos de primeira classe e ordem superior
Assinaturas
Usadas para definir interfaces de módulos
module type EQ = sig
type t
val eq : t * t -> bool
end;;
Uma type class pode ser usada de maneira similar
class EQ t where
eq :: (t, t) -> bool
Módulos
OCaml
module IntEQ : EQ with type t = int = struct
type t = int
let eq (x,y) = x == y
end;;
Haskell
instance EQ Int where
eq (x, y) = x == y
Módulos adicionais
OCaml
module IntEQMod10 : EQ with type t = int = struct
type t = int
let eq (x,y) = (x mod 10) == (y mod 10)
end;;
Haskell
newtype Mod10 = Mod10 Int
instance EQ Mod10 where
eq (Mod10 x,Mod10 y) = (x `mod` 10) == (y `mod` 10)
Functors
OCaml
module PairEQ(X : EQ)(Y : EQ) : EQ with type t = X.t * Y.t = struct
type t = X.t * Y.t
let eq ((x1,y1),(x2,y2)) = X.eq (x1,x2) && Y.eq (y1,y2)
end;;
module II = PairEQ(IntEQ)(IntEQ);;
Haskell
instance (EQ a, EQ b) => EQ (a,b) where
eq ((x1,y1),(x2,y2)) = eq (x1,x2) && eq (y1,y2)
More Functors
OCaml
module IntEQMod(N : sig val n : int end) : EQ with type t = int = struct
type t = int
let eq (x,y) = (x mod N.n) == (y mod N.n)
end;;
module IntEQMod13 = IntEQMod(struct let n = 13 end);;
Haskell
-- left as an exercise for the reader
Módulos de primeira classe
OCaml
let eqs = [(module IntEQMod(struct let n = 13 end) : EQ with type t = int)
;(module IntEQMod(struct let n = 17 end))];;
# val eqs : (module EQ with type t = int) list = [<module>; <module>]
let f p m = let module M = (val m : EQ with type t = int)
in M.eq p;;
List.map (f (0, 13)) eqs;;
- : bool list = [true; false]
List.map (f (0, 17)) eqs;;
- : bool list = [false; true]
Haskell
-- left as an exercise for the reader